home *** CD-ROM | disk | FTP | other *** search
- "EA IFF 85" Standard for Interchange Format Files
-
- Document Date: January 14, 1985
- From: Jerry Morrison, Electronic Arts
- Status of Standard: Released and in use
-
- 1. Introduction
-
- Standards are Good for Software Developers
-
- As home computer hardware evolves to better and better media machines,
- the demand increases for higher quality, more detailed data. Data
- development gets more expensive, requires more expertise and better
- tools, and has to be shared across projects. Think about several ports
- of a product on one CD-ROM with 500M Bytes of common data!
-
- Development tools need standard interchange file formats. Imagine
- scanning in images of "player" shapes, moving them to a paint program
- for editing, then incorporating them into a game. Or writing a theme
- song with a Macintosh score editor and incorporating it into an Amiga
- game. The data must at times be transformed, clipped, filled out, and
- moved across machine kinds. Media projects will depend on data transfer
- from graphic, music, sound effect, animation, and script tools.
-
- Standards are Good for Software Users
-
- Customers should be able to move their own data between independently
- developed software products. And they should be able to buy data
- libraries usable across many such products. The types of data objects to
- exchange are open-ended and include plain and formatted text, raster and
- structured graphics, fonts, music, sound effects, musical instrument
- descriptions, and animation.
-
- The problem with expedient file formats typically memory dumps is that
- they're too provincial. By designing data for one particular use (e.g. a
- screen snapshot), they preclude future expansion (would you like a full
- page picture? a multi-page document?). In neglecting the possibility
- that other programs might read their data, they fail to save contextual
- information (how many bit planes? what resolution?). Ignoring that other
- programs might create such files, they're intolerant of extra data
- (texture palette for a picture editor), missing data (no color map), or
- minor variations (smaller image). In practice, a filed representation
- should rarely mirror an in-memory representation. The former should be
- designed for longevity; the latter to optimize the manipulations of a
- particular program. The same filed data will be read into different
- memory formats by different programs.
-
- The IFF philosophy: "A little behind-the-scenes conversion when programs
- read and write files is far better than NxM explicit conversion
- utilities for highly specialized formats."
-
- So we need some standardization for data interchange among development
- tools and products. The more developers that adopt a standard, the
- better for all of us and our customers.
-
- Here is "EA IFF 1985"
-
- Here is our offering: Electronic Arts' IFF standard for Interchange File
- Format. The full name is "EA IFF 1985". Alternatives and justifications
- are included for certain choices. Public domain subroutine packages and
- utility programs are available to make it easy to write and use
- IFF-compatible programs.
-
- Part 1 introduces the standard. Part 2 presents its requirements and
- background. Parts 3, 4, and 5 define the primitive data types, FORMs,
- and LISTs, respectively, and how to define new high level types. Part 6
- specifies the top level file structure. Appendix A is included for quick
- reference and Appendix B names the committee responsible for this
- standard.
-
- References
-
- American National Standard Additional Control Codes for Use with ASCII,
- ANSI standard 3.64-1979 for an 8-bit character set. See also ISO
- standard 2022 and ISO/DIS standard 6429.2.
-
- Amiga[tm] is a trademark of Commodore-Amiga, Inc.
-
- C, A Reference Manual, Samuel P. Harbison and Guy L. Steele Jr., Tartan
- Laboratories. Prentice-Hall, Englewood Cliffs, NJ, 1984.
-
- Compiler Construction, An Advanced Course, edited by F. L. Bauer and J.
- Eickel (Springer-Verlag, 1976). This book is one of many sources for
- information on recursive descent parsing.
-
- DIF Technical Specification (c)1981 by Software Arts, Inc. DIF[tm] is
- the format for spreadsheet data interchange developed by Software Arts,
- Inc. DIF[tm] is a trademark of Software Arts, Inc.
-
- Electronic Arts[tm] is a trademark of Electronic Arts.
-
- "FTXT" IFF Formatted Text, from Electronic Arts. IFF supplement document
- for a text format.
-
- Inside Macintosh (c) 1982, 1983, 1984, 1985 Apple Computer, Inc., a
- programmer's reference manual. Apple(R) is a trademark of Apple
- Computer, Inc. Macintosh[tm] is a trademark licensed to Apple Computer,
- Inc.
-
- "ILBM" IFF Interleaved Bitmap, from Electronic Arts. IFF supplement
- document for a raster image format.
-
- M68000 16/32-Bit Microprocessor Programmer's Reference Manual(c) 1984,
- 1982, 1980, 1979 by Motorola, Inc.
-
- PostScript Language Manual (c) 1984 Adobe Systems Incorporated.
- PostScript[tm] is a trademark of Adobe Systems, Inc. Times and
- Helvetica(R) are trademarks of Allied Corporation.
-
- InterScript: A Proposal for a Standard for the Interchange of Editable
- Documents (c)1984 Xerox Corporation. Introduction to InterScript (c)
- 1985 Xerox Corporation.
-
- 2. Background for Designers
-
- Part 2 is about the background, requirements, and goals for the
- standard. It's geared for people who want to design new types of IFF
- objects. People just interested in using the standard may wish to skip
- this part.
-
- What Do We Need?
-
- A standard should be long on prescription and short on overhead. It
- should give lots of rules for designing programs and data files for
- synergy. But neither the programs nor the files should cost too much
- more than the expedient variety. While we're looking to a future with
- CD-ROMs and perpendicular recording, the standard must work well on
- floppy disks.
-
- For program portability, simplicity, and efficiency, formats should be
- designed with more than one implementation style in mind. (In practice,
- pure stream I/O is adequate although random access makes it easier to
- write files.) It ought to be possible to read one of many objects in a
- file without scanning all the preceding data. Some programs need to read
- and play out their data in real time, so we need good compromises
- between generality and efficiency.
-
- As much as we need standards, they can't hold up product schedules. So
- we also need a kind of decentralized extensibility where any software
- developer can define and refine new object types without some "standards
- authority" in the loop. Developers must be able to extend existing
- formats in a forward- and backward-compatible way. A central repository
- for design information and example programs can help us take full
- advantage of the standard.
-
- For convenience, data formats should heed the restrictions of various
- processors and environments. E.g. word-alignment greatly helps 68000
- access at insignificant cost to 8088 programs.
-
- Other goals include the ability to share common elements over a list of
- objects and the ability to construct composite objects containing other
- data objects with structural information like directories.
-
- And finally, "Simple things should be simple and complex things should
- be possible." Alan Kay.
-
- Think Ahead
-
- Let's think ahead and build programs that read and write files for each
- other and for programs yet to be designed. Build data formats to last
- for future computers so long as the overhead is acceptable. This extends
- the usefulness and life of today's programs and data.
-
- To maximize interconnectivity, the standard file structure and the
- specific object formats must all be general and extensible. Think ahead
- when designing an object. It should serve many purposes and allow many
- programs to store and read back all the information they need; even
- squeeze in custom data. Then a programmer can store the available data
- and is encouraged to include fixed contextual details. Recipient
- programs can read the needed parts, skip unrecognized stuff, default
- missing data, and use the stored context to help transform the data as
- needed.
-
- Scope
-
- IFF addresses these needs by defining a standard file structure, some
- initial data object types, ways to define new types, and rules for
- accessing these files. We can accomplish a great deal by writing
- programs according to this standard, but don't expect direct
- compatibility with existing software. We'll need conversion programs to
- bridge the gap from the old world.
-
- IFF is geared for computers that readily process information in 8-bit
- bytes. It assumes a "physical layer" of data storage and transmission
- that reliably maintains "files" as strings of 8-bit bytes. The standard
- treats a "file" as a container of data bytes and is independent of how
- to find a file and whether it has a byte count.
-
- This standard does not by itself implement a clipboard for cutting and
- pasting data between programs. A clipboard needs software to mediate
- access, to maintain a "contents version number" so programs can detect
- updates, and to manage the data in "virtual memory".
-
- Data Abstraction
-
- The basic problem is how to represent information in a way that's
- program-independent, compiler- independent, machine-independent, and
- device-independent.
-
- The computer science approach is "data abstraction", also known as
- "objects", "actors", and "abstract data types". A data abstraction has a
- "concrete representation" (its storage format), an "abstract
- representation" (its capabilities and uses), and access procedures that
- isolate all the calling software from the concrete representation. Only
- the access procedures touch the data storage. Hiding mutable details
- behind an interface is called "information hiding". What data
- abstraction does is abstract from details of implementing the object,
- namely the selected storage representation and algorithms for
- manipulating it.
-
- The power of this approach is modularity. By adjusting the access
- procedures we can extend and restructure the data without impacting the
- interface or its callers. Conversely, we can extend and restructure the
- interface and callers without making existing data obsolete. It's great
- for interchange!
-
- But we seem to need the opposite: fixed file formats for all programs to
- access. Actually, we could file data abstractions ("filed objects") by
- storing the data and access procedures together. We'd have to encode the
- access procedures in a standard machine-independent programming language
- la PostScript. Even still, the interface can't evolve freely since we
- can't update all copies of the access procedures. So we'll have to
- design our abstract representations for limited evolution and occasional
- revolution (conversion).
-
- In any case, today's microcomputers can't practically store data
- abstractions. They can do the next best thing: store arbitrary types of
- data in "data chunks", each with a type identifier and a length count.
- The type identifier is a reference by name to the access procedures (any
- local implementation). The length count enables storage-level object
- operations like "copy" and "skip to next" independent of object type.
-
- Chunk writing is straightforward. Chunk reading requires a trivial
- parser to scan each chunk and dispatch to the proper access/conversion
- procedure. Reading chunks nested inside other chunks requires recursion,
- but no lookahead or backup.
-
- That's the main idea of IFF. There are, of course, a few other detailsI
-
- Previous Work
-
- Where our needs are similar, we borrow from existing standards.
-
- Our basic need to move data between independently developed programs is
- similar to that addressed by the Apple Macintosh desk scrap or
- "clipboard" [Inside Macintosh chapter "Scrap Manager"]. The Scrap
- Manager works closely with the Resource Manager, a handy filer and
- swapper for data objects (text strings, dialog window templates,
- pictures, fontsI) including types yet to be designed [Inside Macintosh
- chapter "Resource Manager"]. The Resource Manager is a kin to
- Smalltalk's object swapper.
-
- We will probably write a Macintosh desk accessory that converts IFF
- files to and from the Macintosh clipboard for quick and easy interchange
- with programs like MacPaint and Resource Mover.
-
- Macintosh uses a simple and elegant scheme of 4-character "identifiers"
- to identify resource types, clipboard format types, file types, and file
- creator programs. Alternatives are unique ID numbers assigned by a
- central authority or by hierarchical authorities, unique ID numbers
- generated by algorithm, other fixed length character strings, and
- variable length strings. Character string identifiers double as readable
- signposts in data files and programs. The choice of 4 characters is a
- good tradeoff between storage space, fetch/compare/store time, and name
- space size. We'll honor Apple's designers by adopting this scheme.
-
- "PICT" is a good example of a standard structured graphics format
- (including raster images) and its many uses [Inside Macintosh chapter
- "QuickDraw"]. Macintosh provides QuickDraw routines in ROM to create,
- manipulate, and display PICTs. Any application can create a PICT by
- simply asking QuickDraw to record a sequence of drawing commands. Since
- it's just as easy to ask QuickDraw to render a PICT to a screen or a
- printer, it's very effective to pass them between programs, say from an
- illustrator to a word processor. An important feature is the ability to
- store "comments" in a PICT which QuickDraw will ignore. Actually, it
- passes them to your optional custom "comment handler".
-
- PostScript, Adobe's print file standard, is a more general way to
- represent any print image (which is a specification for putting marks on
- paper) [PostScript Language Manual]. In fact, PostScript is a
- full-fledged programming language. To interpret a PostScript program is
- to render a document on a raster output device. The language is defined
- in layers: a lexical layer of identifiers, constants, and operators; a
- layer of reverse polish semantics including scope rules and a way to
- define new subroutines; and a printing-specific layer of built-in
- identifiers and operators for rendering graphic images. It is clearly a
- powerful (Turing equivalent) image definition language. PICT and a
- subset of PostScript are candidates for structured graphics standards.
-
- A PostScript document can be printed on any raster output device
- (including a display) but cannot generally be edited. That's because the
- original flexibility and constraints have been discarded. Besides, a
- PostScript program may use arbitrary computation to supply parameters
- like placement and size to each operator. A QuickDraw PICT, in
- comparison, is a more restricted format of graphic primitives
- parameterized by constants. So a PICT can be edited at the level of the
- primitives, e.g. move or thicken a line. It cannot be edited at the
- higher level of, say, the bar chart data which generated the picture.
-
- PostScript has another limitation: Not all kinds of data amount to marks
- on paper. A musical instrument description is one example. PostScript is
- just not geared for such uses.
-
- "DIF" is another example of data being stored in a general format usable
- by future programs [DIF Technical Specification]. DIF is a format for
- spreadsheet data interchange. DIF and PostScript are both expressed in
- plain ASCII text files. This is very handy for printing, debugging,
- experimenting, and transmitting across modems. It can have substantial
- cost in compaction and read/write work, depending on use. We won't store
- IFF files this way but we could define an ASCII alternate representation
- with a converter program.
-
- InterScript is Xerox' standard for interchange of editable documents
- [Introduction to InterScript]. It approaches a harder problem: How to
- represent editable word processor documents that may contain formatted
- text, pictures, cross-references like figure numbers, and even highly
- specialized objects like mathematical equations? InterScript aims to
- define one standard representation for each kind of information. Each
- InterScript-compatible editor is supposed to preserve the objects it
- doesn't understand and even maintain nested cross-references. So a
- simple word processor would let you edit the text of a fancy document
- without discarding the equations or disrupting the equation numbers.
-
- Our task is similarly to store high level information and preserve as
- much content as practical while moving it between programs. But we need
- to span a larger universe of data types and cannot expect to centrally
- define them all. Fortunately, we don't need to make programs preserve
- information that they don't understand. And for better or worse, we
- don't have to tackle general-purpose cross-references yet.
-
-
- 3. Primitive Data Types
-
- Atomic components such as integers and characters that are interpretable
- directly by the CPU are specified in one format for all processors. We
- chose a format that's most convenient for the Motorola MC68000 processor
- [M68000 16/32-Bit Microprocessor Programmer's Reference Manual].
-
- N.B.: Part 3 dictates the format for "primitive" data types where and
- only where used in the overall file structure and standard kinds of
- chunks (Cf. Chunks). The number of such occurrences will be small enough
- that the costs of conversion, storage, and management of processor-
- specific files would far exceed the costs of conversion during I/O by
- "foreign" programs. A particular data chunk may be specified with a
- different format for its internal primitive types or with processor- or
- environment- speci fic variants if necessary to optimize local usage.
- Since that hurts data interchange, it's not recommended. (Cf. Designing
- New Data Sections, in Part 4.)
-
- Alignment
-
- All data objects larger than a byte are aligned on even byte addresses
- relative to the start of the file. This may require padding. Pad bytes
- are to be written as zeros, but don't count on that when reading.
-
- This means that every odd-length "chunk" (see below) must be padded so
- that the next one will fall on an even boundary. Also, designers of
- structures to be stored in chunks should include pad fields where needed
- to align every field larger than a byte. Zeros should be stored in all
- the pad bytes.
-
- Justification: Even-alignment causes a little extra work for files that
- are used only on certain processors but allows 68000 programs to
- construct and scan the data in memory and do block I/O. You just add an
- occasional pad field to data structures that you're going to block
- read/write or else stream read/write an extra byte. And the same source
- code works on all processors. Unspecified alignment, on the other hand,
- would force 68000 programs to (dis)assemble word and long-word data one
- byte at a time. Pretty cumbersome in a high level language. And if you
- don't conditionally compile that out for other processors, you won't
- gain anything.
-
- Numbers
-
- Numeric types supported are two's complement binary integers in the
- format used by the MC68000 processor high byte first, high word first
- the reverse of 8088 and 6502 format. They could potentially include
- signed and unsigned 8, 16, and 32 bit integers but the standard only
- uses the following:
-
- UBYTE 8 bits
- unsigned WORD 16 bits
- signed UWORD 16 bits
- unsigned LONG 32 bits signed
-
- The actual type definitions depend on the CPU and the compiler. In this
- document, we'll express data type definitions in the C programming
- language. [See C, A Reference Manual.] In 68000 Lattice C:
-
- typedef unsigned char UBYTE; /* 8 bits unsigned */
- typedef short WORD; /* 16 bits signed */
- typedef unsigned short UWORD; /* 16 bits unsigned */
- typedef long LONG; /* 32 bits signed */
-
- Characters
-
- The following character set is assumed wherever characters are used,
- e.g. in text strings, IDs, and TEXT chunks (see below).
-
- Characters are encoded in 8-bit ASCII. Characters in the range NUL (hex
- 0) through DEL (hex 7F) are well defined by the 7-bit ASCII standard.
- IFF uses the graphic group RJS (SP, hex 20) through R~S (hex 7E).
-
- Most of the control character group hex 01 through hex 1F have no
- standard meaning in IFF. The control character LF (hex 0A) is defined as
- a "newline" character. It denotes an intentional line break, that is, a
- paragraph or line terminator. (There is no way to store an automatic
- line break. That is strictly a function of the margins in the
- environment the text is placed.) The control character ESC (hex 1B) is a
- reserved escape character under the rules of ANSI standard 3.64-1979
- American National Standard Additional Control Codes for Use with ASCII,
- ISO standard 2022, and ISO/DIS standard 6429.2.
-
- Characters in the range hex 7F through hex FF are not globally defined
- in IFF. They are best left reserved for future standardization. But note
- that the FORM type FTXT (formatted text) defines the meaning of these
- characters within FTXT forms. In particular, character values hex 7F
- through hex 9F are control codes while characters hex A0 through hex FF
- are extended graphic characters like , as per the ISO and ANSI standards
- cited above. [See the supplementary document "FTXT" IFF Formatted Text.]
-
- Dates
-
- A "creation date" is defined as the date and time a stream of data bytes
- was created. (Some systems call this a "last modified date".) Editing
- some data changes its creation date. Moving the data between volumes or
- machines does not.
-
- The IFF standard date format will be one of those used in MS-DOS,
- Macintosh, or Amiga DOS (probably a 32-bit unsigned number of seconds
- since a reference point). Issue: Investigate these three.
-
- Type IDs
-
- A "type ID", "property name", "FORM type", or any other IFF identifier
- is a 32-bit value: the concatenation of four ASCII characters in the
- range R S (SP, hex 20) through R~S (hex 7E). Spaces (hex 20) should not
- precede printing characters; trailing spaces are ok. Control characters
- are forbidden.
-
- typedef CHAR ID[4];
-
- IDs are compared using a simple 32-bit case-dependent equality test.
-
- Data section type IDs (aka FORM types) are restriced IDs. (Cf. Data
- Sections.) Since they may be stored in filename extensions (Cf. Single
- Purpose Files) lower case letters and punctuation marks are forbidden.
- Trailing spaces are ok.
-
- Carefully choose those four characters when you pick a new ID. Make them
- mnemonic so programmers can look at an interchange format file and
- figure out what kind of data it contains. The name space makes it
- possible for developers scattered around the globe to generate ID values
- with minimal collisions so long as they choose specific names like
- "MUS4" instead of general ones like "TYPE" and "FILE". EA will
- "register" new FORM type IDs and format descriptions as they're devised,
- but collisions will be improbable so there will be no pressure on this
- "clearinghouse" process. Appendix A has a list of currently defined IDs.
-
- Sometimes it's necessary to make data format changes that aren't
- backward compatible. Since IDs are used to denote data formats in IFF,
- new IDs are chosen to denote revised formats. Since programs won't read
- chunks whose IDs they don't recognize (see Chunks, below), the new IDs
- keep old programs from stumbling over new data. The conventional way to
- chose a "revision" ID is to increment the last character if it's a digit
- or else change the last character to a digit. E.g. first and second
- revisions of the ID "XY" would be "XY1" and "XY2". Revisions of "CMAP"
- would be "CMA1" and "CMA2".
-
- Chunks
-
- Chunks are the building blocks in the IFF structure. The form expressed
- as a C typedef is:
-
- typedef struct {
- ID ckID;
- LONG ckSize; /* sizeof(ckData) */
- UBYTE ckData[/* ckSize */];
- } Chunk;
-
- We can diagram an example chunk a "CMAP" chunk containing 12 data bytes
- like this:
- ----------------
- ckID: | 'CMAP' |
- ckSize: | 12 |
- ckData: | 0, 0, 0, 32 | --------
- | 0, 0, 64, 0 | 12 bytes
- | 0, 0, 64, 0 | ---------
- ----------------
-
- The fixed header part means "Here's a type ckID chunk with ckSize bytes
- of data."
-
- The ckID identifies the format and purpose of the chunk. As a rule, a
- program must recognize ckID to interpret ckData. It should skip over all
- unrecognized chunks. The ckID also serves as a format version number as
- long as we pick new IDs to identify new formats of ckData (see above).
-
- The following ckIDs are universally reserved to identify chunks with
- particular IFF meanings: "LIST", "FORM", "PROP", "CAT ", and " ". The
- special ID " " (4 spaces) is a ckID for "filler" chunks, that is, chunks
- that fill space but have no meaningful contents. The IDs "LIS1" through
- "LIS9", "FOR1" through "FOR9", and "CAT1" through "CAT9" are reserved
- for future "version number" variations. All IFF-compatible software must
- account for these 23 chunk IDs. Appendix A has a list of predefined IDs.
-
- The ckSize is a logical block size how many data bytes are in ckData. If
- ckData is an odd number of bytes long, a 0 pad byte follows which is not
- included in ckSize. (Cf. Alignment.) A chunk's total physical size is
- ckSize rounded up to an even number plus the size of the header. So the
- smallest chunk is 8 bytes long with ckSize = 0. For the sake of
- following chunks, programs must respect every chunk's ckSize as a
- virtual end-of-file for reading its ckData even if that data is
- malformed, e.g. if nested contents are truncated.
-
- We can describe the syntax of a chunk as a regular expression with "#"
- representing the ckSize, i.e. the length of the following {braced}
- bytes. The "[0]" represents a sometimes needed pad byte. (The regular
- expressions in this document are collected in Appendix A along with an
- explanation of notation.)
-
- Chunk ::= ID #{ UBYTE* } [0]
-
- One chunk output technique is to stream write a chunk header, stream
- write the chunk contents, then random access back to the header to fill
- in the size. Another technique is to make a preliminary pass over the
- data to compute the size, then write it out all at once.
-
- Strings, String Chunks, and String Properties
-
- In a string of ASCII text, LF denotes a forced line break (paragraph or
- line terminator). Other control characters are not used. (Cf.
- Characters.)
-
- The ckID for a chunk that contains a string of plain, unformatted text
- is "TEXT". As a practical matter, a text string should probably not be
- longer than 32767 bytes. The standard allows up to 231 - 1 bytes.
-
- When used as a data property (see below), a text string chunk may be 0
- to 255 characters long. Such a string is readily converted to a C string
- or a Pascal STRING[255]. The ckID of a property must be the property
- name, not "TEXT".
-
- When used as a part of a chunk or data property, restricted C string
- format is normally used. That means 0 to 255 characters followed by a
- NUL byte (ASCII value 0).
-
- Data Properties
-
- Data properties specify attributes for following (non-property) chunks.
- A data property essentially says "identifier = value", for example "XY =
- (10, 200)", telling something about following chunks. Properties may
- only appear inside data sections ("FORM" chunks, cf. Data Sections) and
- property sections ("PROP" chunks, cf. Group PROP).
-
- The form of a data property is a special case of Chunk. The ckID is a
- property name as well as a property type. The ckSize should be small
- since data properties are intended to be accumulated in RAM when reading
- a file. (256 bytes is a reasonable upper bound.) Syntactically:
-
- Property::= Chunk
-
- When designing a data object, use properties to describe context
- information like the size of an image, even if they don't vary in your
- program. Other programs will need this information.
-
- Think of property settings as assignments to variables in a programming
- language. Multiple assignments are redundant and local assignments
- temporarily override global assignments. The order of assignments
- doesn't matter as long as they precede the affected chunks. (Cf. LISTs,
- CATs, and Shared Properties.)
-
- Each object type (FORM type) is a local name space for property IDs.
- Think of a "CMAP" property in a "FORM ILBM" as the qualified ID
- "ILBM.CMAP". Property IDs specified when an object type is designed (and
- therefore known to all clients) are called "standard" while specialized
- ones added later are "nonstandard".
-
- Links
-
- Issue: A standard mechanism for "links" or "cross references" is very
- desirable for things like combining images and sounds into animations.
- Perhaps we'll define "link" chunks within FORMs that refer to other
- FORMs or to specific chunks within the same and other FORMs. This needs
- further work. EA IFF 1985 has no standard link mechanism.
-
- For now, it may suffice to read a list of, say, musical instruments, and
- then just refer to them within a musical score by index number.
-
- File References
-
- Issue: We may need a standard form for references to other files. A
- "file ref" could name a directory and a file in the same type of
- operating system as the ref's originator. Following the reference would
- expect the file to be on some mounted volume. In a network environment,
- a file ref could name a server, too.
-
- Issue: How can we express operating-system independent file refs?
-
- Issue: What about a means to reference a portion of another file? Would
- this be a "file ref" plus a reference to a "link" within the target
- file?
-
- 4. Data Sections
-
- The first thing we need of a file is to check: Does it contain IFF data
- and, if so, does it contain the kind of data we're looking for? So we
- come to the notion of a "data section".
-
- A "data section" or IFF "FORM" is one self-contained "data object" that
- might be stored in a file by itself. It is one high level data object
- such as a picture or a sound effect. The IFF structure "FORM" makes it
- self- identifying. It could be a composite object like a musical score
- with nested musical instrument descriptions.
-
- Group FORM
-
- A data section is a chunk with ckID "FORM" and this arrangement:
-
- FORM ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)* }
- FormType::= ID LocalChunk ::= Property | Chunk
-
- The ID "FORM" is a syntactic keyword like "struct" in C. Think of a
- "struct ILBM" containing a field "CMAP". If you see "FORM" you'll know
- to expect a FORM type ID (the structure name, "ILBM" in this example)
- and a particular contents arrangement or "syntax" (local chunks, FORMs,
- LISTs, and CATs). (LISTs and CATs are discussed in part 5, below.) A
- "FORM ILBM", in particular, might contain a local chunk "CMAP", an
- "ILBM.CMAP" (to use a qualified name).
-
- So the chunk ID "FORM" indicates a data section. It implies that the
- chunk contains an ID and some number of nested chunks. In reading a
- FORM, like any other chunk, programs must respect its ckSize as a
- virtual end-of-file for reading its contents, even if they're truncated.
-
- The FormType (or FORM type) is a restricted ID that may not contain
- lower case letters or punctuation characters. (Cf. Type IDs. Cf. Single
- Purpose Files.)
-
- The type-specific information in a FORM is composed of its "local
- chunks": data properties and other chunks. Each FORM type is a local
- name space for local chunk IDs. So "CMAP" local chunks in other FORM
- types may be unrelated to "ILBM.CMAP". More than that, each FORM type
- defines semantic scope. If you know what a FORM ILBM is, you'll know
- what an ILBM.CMAP is.
-
- Local chunks defined when the FORM type is designed (and therefore known
- to all clients of this type) are called "standard" while specialized
- ones added later are "nonstandard".
-
- Among the local chunks, property chunks give settings for various
- details like text font while the other chunks supply the essential
- information. This distinction is not clear cut. A property setting
- cancelled by a later setting of the same property has effect only on
- data chunks in between. E.g. in the sequence:
-
- prop1 = x (propN = value)* prop1 = y
-
- where the propNs are not prop1, the setting prop1 = x has no effect.
-
- The following universal chunk IDs are reserved inside any FORM: "LIST",
- "FORM", "PROP", "CAT ", "JJJJ", "LIS1" through "LIS9", "FOR1" through
- "FOR9", and "CAT1" through "CAT9". (Cf. Chunks. Cf. Group LIST. Cf.
- Group PROP.) For clarity, these universal chunk names may not be FORM
- type IDs, either.
-
- Part 5, below, talks about grouping FORMs into LISTs and CATs. They let
- you group a bunch of FORMs but don't impose any particular meaning or
- constraints on the grouping. Read on.
-
- Composite FORMs
-
- A FORM chunk inside a FORM is a full-fledged data section. This means
- you can build a composite object like a multi-frame animation sequence
- from available picture FORMs and sound effect FORMs. You can insert
- additional chunks with information like frame rate and frame count.
-
- Using composite FORMs, you leverage on existing programs that create and
- edit the component FORMs. Those editors may even look into your
- composite object to copy out its type of component, although it'll be
- the rare program that's fancy enough to do that. Such editors are not
- allowed to replace their component objects within your composite object.
- That's because the IFF standard lets you specify consistency
- requirements for the composite FORM such as maintaining a count or a
- directory of the components. Only programs that are written to uphold
- the rules of your FORM type should create or modify such FORMs.
-
- Therefore, in designing a program that creates composite objects, you
- are strongly requested to provide a facility for your users to import
- and export the nested FORMs. Import and export could move the data
- through a clipboard or a file.
-
- Here are several existing FORM types and rules for defining new ones.
-
- FTXT
-
- An FTXT data section contains text with character formatting information
- like fonts and faces. It has no paragraph or document formatting
- information like margins and page headers. FORM FTXT is well matched to
- the text representation in Amiga's Intuition environment. See the
- supplemental document "FTXT" IFF Formatted Text.
-
- ILBM
-
- "ILBM" is an InterLeaved BitMap image with color map; a
- machine-independent format for raster images. FORM ILBM is the standard
- image file format for the Commodore-Amiga computer and is useful in
- other environments, too. See the supplemental document "ILBM" IFF
- Interleaved Bitmap.
-
- PICS
-
- The data chunk inside a "PICS" data section has ID "PICT" and holds a
- QuickDraw picture. Issue: Allow more than one PICT in a PICS? See Inside
- Macintosh chapter "QuickDraw" for details on PICTs and how to create and
- display them on the Macintosh computer.
-
- The only standard property for PICS is "XY", an optional property that
- indicates the position of the PICT relative to "the big picture". The
- contents of an XY is a QuickDraw Point.
-
- Note: PICT may be limited to Macintosh use, in which case there'll be
- another format for structured graphics in other environments.
-
- Other Macintosh Resource Types
-
- Some other Macintosh resource types could be adopted for use within IFF
- files; perhaps MWRT, ICN, ICN#, and STR#.
-
- Issue: Consider the candidates and reserve some more IDs.
-
- Designing New Data Sections
-
- Supplemental documents will define additional object types. A supplement
- needs to specify the object's purpose, its FORM type ID, the IDs and
- formats of standard local chunks, and rules for generating and
- interpreting the data. It's a good idea to supply typedefs and an
- example source program that accesses the new object. See "ILBM" IFF
- Interleaved Bitmap for a good example.
-
- Anyone can pick a new FORM type ID but should reserve it with Electronic
- Arts at their earliest convenience. [Issue: EA contact person? Hand this
- off to another organization?] While decentralized format definitions and
- extensions are possible in IFF, our preference is to get design
- consensus by committee, implement a program to read and write it,
- perhaps tune the format, and then publish the format with example code.
- Some organization should remain in charge of answering questions and
- coordinating extensions to the format.
-
- If it becomes necessary to revise the design of some data section, its
- FORM type ID will serve as a version number (Cf. Type IDs). E.g. a
- revised "VDEO" data section could be called "VDE1". But try to get by
- with compatible revisions within the existing FORM type.
-
- In a new FORM type, the rules for primitive data types and
- word-alignment (Cf. Primitive Data Types) may be overriden for the
- contents of its local chunks but not for the chunk structure itself if
- your documentation spells out the deviations. If machine-specific type
- variants are needed, e.g. to store vast numbers of integers in reverse
- bit order, then outline the conversion algorithm and indicate the
- variant inside each file, perhaps via different FORM types. Needless to
- say, variations should be minimized.
-
- In designing a FORM type, encapsulate all the data that other programs
- will need to interpret your files. E.g. a raster graphics image should
- specify the image size even if your program always uses 320 x 200 pixels
- x 3 bitplanes. Receiving programs are then empowered to append or clip
- the image rectangle, to add or drop bitplanes, etc. This enables a lot
- more compatibility.
-
- Separate the central data (like musical notes) from more specialized
- information (like note beams) so simpler programs can extract the
- central parts during read-in. Leave room for expansion so other programs
- can squeeze in new kinds of information (like lyrics). And remember to
- keep the property chunks manageably short let's say 2 256 bytes.
-
- When designing a data object, try to strike a good tradeoff between a
- super-general format and a highly-specialized one. Fit the details to at
- least one particular need, for example a raster image might as well
- store pixels in the current machine's scan order. But add the kind of
- generality that makes it usable with foreseeable hardware and software.
- E.g. use a whole byte for each red, green, and blue color value even if
- this year's computer has only 4-bit video DACs. Think ahead and help
- other programs so long as the overhead is acceptable. E.g. run compress
- a raster by scan line rather than as a unit so future programs can swap
- images by scan line to and from secondary storage.
-
- Try to design a general purpose "least common multiple" format that
- encompasses the needs of many programs without getting too complicated.
- Let's coalesce our uses around a few such formats widely separated in
- the vast design space. Two factors make this flexibility and simplicity
- practical. First, file storage space is getting very plentiful, so
- compaction is not a priority. Second, nearly any locally-performed data
- conversion work during file reading and writing will be cheap compared
- to the I/O time.
-
- It must be ok to copy a LIST or FORM or CAT intact, e.g. to incorporate
- it into a composite FORM. So any kind of internal references within a
- FORM must be relative references. They could be relative to the start of
- the containing FORM, relative from the referencing chunk, or a sequence
- number into a collection.
-
- With composite FORMs, you leverage on existing programs that create and
- edit the components. If you write a program that creates composite
- objects, please provide a facility for your users to import and export
- the nested FORMs. The import and export functions may move data through
- a separate file or a clipboard.
-
- Finally, don't forget to specify all implied rules in detail.
-
-
- 5. LISTs, CATs, and Shared Properties
-
- Data often needs to be grouped together like a list of icons. Sometimes
- a trick like arranging little images into a big raster works, but
- generally they'll need to be structured as a first class group. The
- objects "LIST" and "CAT" are IFF-universal mechanisms for this purpose.
-
- Property settings sometimes need to be shared over a list of similar
- objects. E.g. a list of icons may share one color map. LIST provides a
- means called "PROP" to do this. One purpose of a LIST is to define the
- scope of a PROP. A "CAT", on the other hand, is simply a concatenation
- of objects.
-
- Simpler programs may skip LISTs and PROPs altogether and just handle
- FORMs and CATs. All "fully-conforming" IFF programs also know about "CAT
- ", "LIST", and "PROP". Any program that reads a FORM inside a LIST must
- process shared PROPs to correctly interpret that FORM.
-
- Group CAT
-
- A CAT is just an untyped group of data objects.
-
- Structurally, a CAT is a chunk with chunk ID "CAT " containing a
- "contents type" ID followed by the nested objects. The ckSize of each
- contained chunk is essentially a relative pointer to the next one.
-
- CAT ::= "CAT " #{ ContentsType (FORM | LIST | CAT)* }
- ContentsType ::= ID -- a hint or an "abstract data type" ID
-
- In reading a CAT, like any other chunk, programs must respect it's
- ckSize as a virtual end-of-file for reading the nested objects even if
- they're malformed or truncated.
-
- The "contents type" following the CAT's ckSize indicates what kind of
- FORMs are inside. So a CAT of ILBMs would store "ILBM" there. It's just
- a hint. It may be used to store an "abstract data type". A CAT could
- just have blank contents ID ("JJJJ") if it contains more than one kind
- of FORM.
-
- CAT defines only the format of the group. The group's meaning is open to
- interpretation. This is like a list in LISP: the structure of cells is
- predefined but the meaning of the contents as, say, an association list
- depends on use. If you need a group with an enforced meaning (an
- "abstract data type" or Smalltalk "subclass"), some consistency
- constraints, or additional data chunks, use a composite FORM instead
- (Cf. Composite FORMs).
-
- Since a CAT just means a concatenation of objects, CATs are rarely
- nested. Programs should really merge CATs rather than nest them.
-
- Group LIST
-
- A LIST defines a group very much like CAT but it also gives a scope for
- PROPs (see below). And unlike CATs, LISTs should not be merged without
- understanding their contents.
-
- Structurally, a LIST is a chunk with ckID "LIST" containing a "contents
- type" ID, optional shared properties, and the nested contents (FORMs,
- LISTs, and CATs), in that order. The ckSize of each contained chunk is a
- relative pointer to the next one. A LIST is not an arbitrary linked list
- the cells are simply concatenated.
-
- LIST ::= "LIST" #{ ContentsType PROP* (FORM | LIST | CAT)* }
- ContentsType ::= ID
-
- Group PROP
-
- PROP chunks may appear in LISTs (not in FORMs or CATs). They supply
- shared properties for the FORMs in that LIST. This ability to elevate
- some property settings to shared status for a list of forms is useful
- for both indirection and compaction. E.g. a list of images with the same
- size and colors can share one "size" property and one "color map"
- property. Individual FORMs can override the shared settings.
-
- The contents of a PROP is like a FORM with no data chunks:
-
- PROP ::= "PROP" #{ FormType Property* }
-
- It means, "Here are the shared properties for FORM type <<FormType>."
-
- A LIST may have at most one PROP of a FORM type, and all the PROPs must
- appear before any of the FORMs or nested LISTs and CATs. You can have
- subsequences of FORMs sharing properties by making each subsequence a
- LIST.
-
- Scoping: Think of property settings as variable bindings in nested
- blocks of a programming language. Where in C you could write:
-
- TEXT_FONT text_font = Courier; /* program's global default */
-
- File(); {
- TEXT_FONT text_font = TimesRoman; /* shared setting */
-
- {
- TEXT_FONT text_font = Helvetica; /* local setting */
- Print("Hello ");/* uses font Helvetica */
- }
-
- {
- Print("there.");/* uses font TimesRoman */
- }
- }
-
- An IFF file could contain:
-
- LIST {
- PROP TEXT {
- FONT {TimesRoman} /* shared setting */
- }
-
- FORM TEXT {
- FONT {Helvetica}/* local setting*/
- CHRS {Hello } /* uses font Helvetica */
- }
-
- FORM TEXT {
- CHRS {there.} /* uses font TimesRoman */
- }
- }
-
- The shared property assignments selectively override the reader's global
- defaults, but only for FORMs within the group. A FORM's own property
- assignments selectively override the global and group-supplied values.
- So when reading an IFF file, keep property settings on a stack. They're
- designed to be small enough to hold in main memory.
-
- Shared properties are semantically equivalent to copying those
- properties into each of the nested FORMs right after their FORM type
- IDs.
-
- Properties for LIST
-
- Optional "properties for LIST" store the origin of the list's contents
- in a PROP chunk for the fake FORM type "LIST". They are the properties
- originating program "OPGM", processor family "OCPU", computer type
- "OCMP", computer serial number or network address "OSN ", and user name
- "UNAM". In our imperfect world, these could be called upon to
- distinguish between unintended variations of a data format or to work
- around bugs in particular originating/receiving program pairs. Issue:
- Specify the format of these properties.
-
- A creation date could also be stored in a property but let's ask that
- file creating, editing, and transporting programs maintain the correct
- date in the local file system. Programs that move files between machine
- types are expected to copy across the creation dates.
-
-
- 6. Standard File Structure
-
- File Structure Overview
-
- An IFF file is just a single chunk of type FORM, LIST, or CAT. Therefore
- an IFF file can be recognized by its first 4 bytes: "FORM", "LIST", or
- "CAT ". Any file contents after the chunk's end are to be ignored.
-
- Since an IFF file can be a group of objects, programs that read/write
- single objects can communicate to an extent with programs that
- read/write groups. You're encouraged to write programs that handle all
- the objects in a LIST or CAT. A graphics editor, for example, could
- process a list of pictures as a multiple page document, one page at a
- time.
-
- Programs should enforce IFF's syntactic rules when reading and writing
- files. This ensures robust data transfer. The public domain IFF
- reader/writer subroutine package does this for you. A utility program
- "IFFCheck" is available that scans an IFF file and checks it for
- conformance to IFF's syntactic rules. IFFCheck also prints an outline of
- the chunks in the file, showing the ckID and ckSize of each. This is
- quite handy when building IFF programs. Example programs are also
- available to show details of reading and writing IFF files.
-
- A merge program "IFFJoin" will be available that logically appends IFF
- files into a single CAT group. It "unwraps" each input file that is a
- CAT so that the combined file isn't nested CATs.
-
- If we need to revise the IFF standard, the three anchoring IDs will be
- used as "version numbers". That's why IDs "FOR1" through "FOR9", "LIS1"
- through "LIS9", and "CAT1" through "CAT9" are reserved.
-
- IFF formats are designed for reasonable performance with floppy disks.
- We achieve considerable simplicity in the formats and programs by
- relying on the host file system rather than defining universal grouping
- structures like directories for LIST contents. On huge storage systems,
- IFF files could be leaf nodes in a file structure like a B-tree. Let's
- hope the host file system implements that for us!
-
- Thre are two kinds of IFF files: single purpose files and scrap files.
- They differ in the interpretation of multiple data objects and in the
- file's external type.
-
- Single Purpose Files
-
- A single purpose IFF file is for normal "document" and "archive"
- storage. This is in contrast with "scrap files" (see below) and
- temporary backing storage (non-interchange files).
-
- The external file type (or filename extension, depending on the host
- file system) indicates the file's contents. It's generally the FORM type
- of the data contained, hence the restrictions on FORM type IDs.
-
- Programmers and users may pick an "intended use" type as the filename
- extension to make it easy to filter for the relevant files in a filename
- requestor. This is actually a "subclass" or "subtype" that conveniently
- separates files of the same FORM type that have different uses. Programs
- cannot demand conformity to its expected subtypes without overly
- restricting data interchange since they cannot know about the subtypes
- to be used by future programs that users will want to exchange data
- with.
-
- Issue: How to generate 3-letter MS-DOS extensions from 4-letter FORM
- type IDs?
-
- Most single purpose files will be a single FORM (perhaps a composite
- FORM like a musical score containing nested FORMs like musical
- instrument descriptions). If it's a LIST or a CAT, programs should skip
- over unrecognized objects to read the recognized ones or the first
- recognized one. Then a program that can read a single purpose file can
- read something out of a "scrap file", too.
-
- Scrap Files
-
- A "scrap file" is for maximum interconnectivity in getting data between
- programs; the core of a clipboard function. Scrap files may have type
- "IFF " or filename extension ".IFF".
-
- A scrap file is typically a CAT containing alternate representations of
- the same basic information. Include as many alternatives as you can
- readily generate. This redundancy improves interconnectivity in
- situations where we can't make all programs read and write super-general
- formats. [Inside Macintosh chapter "Scrap Manager".] E.g. a graphically-
- annotated musical score might be supplemented by a stripped down 4-voice
- melody and by a text (the lyrics).
-
- The originating program should write the alternate representations in
- order of "preference": most preferred (most comprehensive) type to least
- preferred (least comprehensive) type. A receiving program should either
- use the first appearing type that it understands or search for its own
- "preferred" type.
-
- A scrap file should have at most one alternative of any type. (A LIST of
- same type objects is ok as one of the alternatives.) But don't count on
- this when reading; ignore extra sections of a type. Then a program that
- reads scrap files can read something out of single purpose files.
-
- Rules for Reader Programs
-
- Here are some notes on building programs that read IFF files. If you use
- the standard IFF reader module "IFFR.C", many of these rules and details
- will be automatically handled. (See "Support Software" in Appendix A.)
- We recommend that you start from the example program "ShowILBM.C". You
- should also read up on recursive descent parsers. [See, for example,
- Compiler Construction, An Advanced Course.]
-
- % The standard is very flexible so many programs can exchange
- data. This implies a program has to scan the file and react to what's
- actually there in whatever order it appears. An IFF reader program
- is a parser.
-
- % For interchange to really work, programs must be willing to
- do some conversion during read-in. If the data isn't exactly what
- you expect, say, the raster is smaller than those created by your
- program, then adjust it. Similarly, your program could crop a large
- picture, add or drop bitplanes, and create/discard a mask plane. The
- program should give up gracefully on data that it can't convert.
-
- % If it doesn't start with "FORM", "LIST", or "CAT ", it's not
- an IFF-85 file.
-
- % For any chunk you encounter, you must recognize its type ID
- to understand its contents.
-
- % For any FORM chunk you encounter, you must recognize its FORM
- type ID to understand the contained "local chunks". Even if you don't
- recognize the FORM type, you can still scan it for nested FORMs, LISTs,
- and CATs of interest.
-
- % Don't forget to skip the pad byte after every odd-length chunk.
-
- % Chunk types LIST, FORM, PROP, and CAT are generic groups. They
- always contain a subtype ID followed by chunks.
-
- % Readers ought to handle a CAT of FORMs in a file. You may treat
- the FORMs like document pages to sequence through or just use the
- first FORM.
-
- % Simpler IFF readers completely skip LISTs. "Fully IFF-conforming"
- readers are those that handle LISTs, even if just to read the first
- FORM from a file. If you do look into a LIST, you must process shared
- properties (in PROP chunks) properly. The idea is to get the correct
- data or none at all.
-
- % The nicest readers are willing to look into unrecognized FORMs
- for nested FORM types that they do recognize. For example, a musical
- score may contain nested instrument descriptions and an animation
- file may contain still pictures.
-
- Note to programmers: Processing PROP chunks is not simple! You'll
- need some background in interpreters with stack frames. If this is
- foreign to you, build programs that read/write only one FORM per file.
- For the more intrepid programmers, the next paragraph summarizes how
- to process LISTs and PROPs. See the general IFF reader module "IFFR.C"
- and the example program "ShowILBM.C" for details.
-
- Allocate a stack frame for every LIST and FORM you encounter and
- initialize it by copying the stack frame of the parent LIST or FORM. At
- the top level, you'll need a stack frame initialized to your program's
- global defaults. While reading each LIST or FORM, store all encountered
- properties into the current stack frame. In the example ShowILBM, each
- stack frame has a place for a bitmap header property ILBM.BMHD and a
- color map property ILBM.CMAP. When you finally get to the ILBM's BODY
- chunk, use the property settings accumulated in the current stack frame.
-
- An alternate implementation would just remember PROPs encountered,
- forgetting each on reaching the end of its scope (the end of the
- containing LIST). When a FORM XXXX is encountered, scan the chunks in
- all remembered PROPs XXXX, in order, as if they appeared before the
- chunks actually in the FORM XXXX. This gets trickier if you read FORMs
- inside of FORMs.
-
- Rules for Writer Programs
-
- Here are some notes on building programs that write IFF files, which is
- much easier than reading them. If you use the standard IFF writer module
- "IFFW.C" (see "Support Software" in Appendix A), many of these rules and
- details will automatically be enforced. See the example program
- "Raw2ILBM.C".
-
- % An IFF file is a single FORM, LIST, or CAT chunk.
-
- % Any IFF-85 file must start with the 4 characters "FORM", "LIST",
- or "CAT ", followed by a LONG ckSize. There should be no data after
- the chunk end.
-
- % Chunk types LIST, FORM, PROP, and CAT are generic. They always
- contain a subtype ID followed by chunks. These three IDs are universally
- reserved, as are "LIS1" through "LIS9", "FOR1" through "FOR9", "CAT1"
- through "CAT9", and " ".
-
- % Don't forget to write a 0 pad byte after each odd-length chunk.
-
- % Four techniques for writing an IFF group: (1) build the data
- in a file mapped into virtual memory, (2) build the data in memory
- blocks and use block I/O, (3) stream write the data piecemeal and
- (don't forget!) random access back to set the group length count,
- and (4) make a preliminary pass to compute the length count then stream
- write the data.
-
- % Do not try to edit a file that you don't know how to create.
- Programs may look into a file and copy out nested FORMs of types that
- they recognize, but don't edit and replace the nested FORMs and don't
- add or remove them. That could make the containing structure inconsistent.
- You may write a new file containing items you copied (or copied and
- modified) from another IFF file, but don't copy structural parts you
- don't understand.
-
- % You must adhere to the syntax descriptions in Appendex A. E.g.
- PROPs may only appear inside LISTs.
-
-
- Appendix A. Reference
-
- Type Definitions
-
- The following C typedefs describe standard IFF structures. Declarations
- to use in practice will vary with the CPU and compiler. For example,
- 68000 Lattice C produces efficient comparison code if we define ID as a
- "LONG". A macro "MakeID" builds these IDs at compile time.
-
- /* Standard IFF types, expressed in 68000 Lattice C. */
-
- typedef unsigned char UBYTE; /* 8 bits unsigned */
- typedef short WORD; /* 16 bits signed */
- typedef unsigned short UWORD; /* 16 bits unsigned */
- typedef long LONG; /* 32 bits signed */
-
- typedef char ID[4]; /* 4 chars in ' ' through '~' */
-
- typedef struct {
- ID ckID;
- LONG ckSize; /* sizeof(ckData) */
- UBYTE ckData[/* ckSize */];
- } Chunk;
-
- /* ID typedef and builder for 68000 Lattice C. */
- typedef LONG ID; /* 4 chars in ' ' through '~' */
- #define MakeID(a,b,c,d) ( (a)<<<<24 | (b)<<<<16 | (c)<<<<8 | (d) )
-
- /* Globally reserved IDs. */
- #define ID_FORM MakeID('F','O','R','M')
- #define ID_LIST MakeID('L','I','S','T')
- #define ID_PROP MakeID('P','R','O','P')
- #define ID_CAT MakeID('C','A','T',' ')
- #define ID_FILLER MakeID(' ',' ',' ',' ')
-
- Syntax Definitions
-
- Here's a collection of the syntax definitions in this document.
-
- Chunk ::= ID #{ UBYTE* } [0]
-
- Property::= Chunk
-
- FORM ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)*
- }
- FormType::= ID
- LocalChunk ::= Property | Chunk
-
- CAT ::= "CAT " #{ ContentsType (FORM | LIST | CAT)* }
- ContentsType ::= ID -- a hint or an "abstract data type" ID
-
- LIST ::= "LIST" #{ ContentsType PROP* (FORM | LIST | CAT)* }
- PROP ::= "PROP" #{ FormType Property* }
-
- In this extended regular expression notation, the token "#" represents a
- ckSize LONG count of the following {braced} data bytes. Literal items
- are shown in "quotes", [square bracketed items] are optional, and "*"
- means 0 or more instances. A sometimes-needed pad byte is shown as
- "[0]".
-
- Defined Chunk IDs
-
- This is a table of currently defined chunk IDs. We may also borrow some
- Macintosh IDs and data formats.
-
- Group chunk IDs
- FORM, LIST, PROP, CAT.
- Future revision group chunk IDs
- FOR1 I FOR9, LIS1 I LIS9, CAT1 I CAT9.
- FORM type IDs
- (The above group chunk IDs may not be used for FORM type IDs.)
- (Lower case letters and punctuation marks are forbidden in FORM
- type IDs.)
- 8SVX 8-bit sampled sound voice, ANBM animated bitmap, FNTR raster
- font, FNTV vector font, FTXT formatted text, GSCR general-use musical
- score, ILBM interleaved raster bitmap image, PDEF Deluxe Print page
- definition, PICS Macintosh picture, PLBM (obsolete), USCR Uhuru Sound
- Software musical score, UVOX Uhuru Sound Software Macintosh voice,
- SMUS simple musical score, VDEO Deluxe Video Construction Set video.
- Data chunk IDs
- "JJJJ", TEXT, PICT.
- PROP LIST property IDs
- OPGM, OCPU, OCMP, OSN, UNAM.
-
-
-
- Support Software
-
- These public domain C source programs are available for use in building
- IFF-compatible programs:
-
- IFF.H, IFFR.C, IFFW.C
-
- IFF reader and writer package.
- These modules handle many of the details of reliably
- reading and writing IFF files.
-
- IFFCheck.C This handy utility program scans an IFF file, checks
- that the contents are well formed, and prints an outline
- of the chunks.
-
- PACKER.H, Packer.C, UnPacker.C
-
- Run encoder and decoder used for ILBM files.
-
- ILBM.H, ILBMR.C, ILBMW.C
-
- Reader and writer support routines for raster image
- FORM ILBM. ILBMR calls IFFR and UnPacker. ILBMW calls
- IFFW and Packer.
-
- ShowILBM.C
- Example caller of IFFR and ILBMR modules. This
- Commodore-Amiga program reads and displays a FORM ILBM.
- Raw2ILBM.C
- Example ILBM writer program. As a demonstration, it
- reads a raw raster image file and writes the image
- as a FORM ILBM file.
- ILBM2Raw.C
- Example ILBM reader program. Reads a FORM ILBM file
- and writes it into a raw raster image.
-
- REMALLOC.H, Remalloc.c
-
- Memory allocation routines used in these examples.
-
- INTUALL.H generic "include almost everything" include-file
- with the sequence of includes correctly specified.
-
- READPICT.H, ReadPict.c
-
- given an ILBM file, read it into a bitmap and
- a color map
-
- PUTPICT.H, PutPict.c
-
- given a bitmap and a color map, save it as
- an ILBM file.
-
- GIO.H, Gio.c generic I/O speedup package. Attempts to speed
- disk I/O by buffering writes and reads.
-
- giocall.c sample call to gio.
-
- ilbmdump.c reads in ILBM file, prints out ascii representation
- for including in C files.
-
- bmprintc.c prints out a C-language representation of data for
- a bitmap.
-
-
-
- Example Diagrams
-
- Here's a box diagram for an example IFF file, a raster image FORM ILBM.
- This FORM contains a bitmap header property chunk BMHD, a color map
- property chunk CMAP, and a raster data chunk BODY. This particular
- raster is 320 x 200 pixels x 3 bit planes uncompressed. The "0" after
- the CMAP chunk represents a zero pad byte; included since the CMAP ch